/**
 * 文件名：@AbstractSoaClientRegister.java <br/>
 * 包名：cn.efunbox.afw.soa.client <br/>
 * 项目名：afw-soa-client <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.soa.client.register;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import cn.efunbox.afw.soa.client.annotation.SoaClientConfig;

/**
 * 类名：AbstractSoaClientRegister  <br />
 *
 * 功能：注册基础实现
 *
 * @author xtwin <br />
 * 创建时间：2016年7月25日 上午10:32:52  <br />
 * @version 2016年7月25日
 */
public abstract class AbstractSoaClientRegister implements SoaClientRegister {
	
	// 日志记录器
	private static final Logger logger = LoggerFactory.getLogger(AbstractSoaClientRegister.class);

	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2016年7月25日 上午10:33:07<br/>
	 * 
	 * @param configs <br/>
	 * @see cn.efunbox.afw.soa.client.register.SoaClientRegister#register(cn.efunbox.afw.soa.client.annotation.SoaClientConfig[])
	 */
	@Override
	public void register(SoaClientConfig... configs) {
		
		logger.info("register configs is : {}", Arrays.toString(configs));
		
		if (null == configs || configs.length == 0) {
			return ;
		}
		
		// 依次执行客户端注册
		for (SoaClientConfig config : configs) {
			
			logger.info("register config : {}", config);
			
			doRegister(config);
		}
	}

	/**
	 * 功能：由子类实现具体注册逻辑 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年7月25日 上午10:35:15 <br/>
	 */
	protected void doRegister(SoaClientConfig config) {
		// 需要扫描的包
		Set<String> basePackages = new HashSet<>(Arrays.asList(config.basePackages()));
		
		logger.info("package is : {}", basePackages);
		
		if (basePackages.isEmpty()) {
			return ;
		}
		
		// 依次处理每个包
		for (String pack : basePackages) {
			// 扫描指定包下的bean
			Set<BeanDefinition> clients = getSanner().findCandidateComponents(pack);
			
			// 依次进行bean注册
			for (BeanDefinition client : clients) {
				
				logger.info("register bean : {}", client.getBeanClassName());
				
				// 注册指定client
				doRegister(getRegistry(), config, client);
			}
		}
	}
	
	/**
	 * 功能：由之实现bean的注册逻辑 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年7月25日 上午10:47:51 <br/>
	 */
	protected abstract void doRegister(BeanDefinitionRegistry registry, SoaClientConfig config, BeanDefinition client);

	/**
	 * 功能：扫描器 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年7月25日 上午10:42:53 <br/>
	 */
	protected ClassPathScanningCandidateComponentProvider getSanner() {
		ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false) {
			@Override
			protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
				
				if (beanDefinition.getMetadata().isIndependent()) {
					if (beanDefinition.getMetadata().isInterface()) {
						return true;
					}
				}
				
				return false;
			}
		};
		scanner.addIncludeFilter(new TypeFilter() {
			@Override
			public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
				return metadataReader.getClassMetadata().isInterface();
			}
		});
		
		return scanner;
	}
	
	/**
	 * 功能：获得注册器 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2016年7月28日 上午9:55:39 <br/>
	 */
	protected abstract BeanDefinitionRegistry getRegistry();
}